package com.erli.exchange.dao.impl;

import java.lang.reflect.ParameterizedType;
import java.util.Date;
import java.util.List;

import com.erli.exchange.dao.BaseDao;
import com.erli.exchange.dao.mapper.BaseMapper;
import com.erli.exchange.core.beans.entity.BaseEntity;

import cn.hutool.core.util.StrUtil;
import tk.mybatis.mapper.entity.Example;

/**
 * 
 * @Package com.erli.exchange.dao.impl
 * @ClassName: BaseDaoImpl
 * @Description:TODO
 * @Author: LeeHo
 * @Date: 2019年3月3日 下午12:25:12
 * 
 * @param <Record>
 */
public abstract class BaseDaoImpl<Record extends BaseEntity> implements BaseDao<Record> {

	public abstract BaseMapper<Record> getBaseMapper();

	@SuppressWarnings("unchecked")
	private Class<Record> getTClass() {
		Class<Record> tClass = (Class<Record>) ((ParameterizedType) getClass().getGenericSuperclass())
				.getActualTypeArguments()[0];
		return tClass;
	}

	@Override
	public Integer insert(Record record) {
		record.setCreateTime(new Date());
		return getBaseMapper().insert(record);
	}

	@Override
	public Integer insertSelective(Record record) {
		record.setCreateTime(new Date());
		return getBaseMapper().insertSelective(record);
	}

	@Override
	public Integer updateById(Record record) {
		record.setUpdateTime(new Date());
		return getBaseMapper().updateByPrimaryKeySelective(record);
	}

	@Override
	public Integer updateByColumn(String column, Object value, Record record) {
		Example example = new Example(getTClass());
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo(column, value);
		return updateByExampleSelective(record, example);
	}

	@Override
	public Integer deleteById(Integer id) {
		return getBaseMapper().deleteByPrimaryKey(id);
	}

	@Override
	public Integer deleteByColumn(String column, Object value) {
		Example example = new Example(getTClass());
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo(column, value);
		return deleteByExample(example);
	}

	@Override
	public Integer deleteByRecord(Record record) {
		return getBaseMapper().delete(record);
	}

	@Override
	public Record findById(Integer id) {
		return getBaseMapper().selectByPrimaryKey(id);
	}

	@Override
	public Record findByColumn(String column, Object value) {
		Example example = new Example(getTClass());
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo(column, value);
		return findByExample(example);
	}

	@Override
	public Record findByRecord(Record record) {
		return getBaseMapper().selectOne(record);
	}

	@Override
	public List<Record> findListByColumn(String column, Object value) {
		Example example = new Example(getTClass());
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo(column, value);
		return findListByExample(example);
	}

	@Override
	public List<Record> findListByRecord(Record record) {
		return findListByRecord(record, null);
	}

	@Override
	public List<Record> findListByRecord(Record record, String orderByClause) {
		Example example = new Example(getTClass());
		example.setOrderByClause(StrUtil.isNotEmpty(orderByClause) ? orderByClause : null);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo(record);
		return findListByExample(example);
	}

	@Override
	public Record findByExample(Example example) {
		this.removeEmptyStringValue(example);
		return getBaseMapper().selectOneByExample(example);
	}

	@Override
	public List<Record> findListByExample(Example example) {
		this.removeEmptyStringValue(example);
		return getBaseMapper().selectByExample(example);
	}

	@Override
	public Integer countByRecord(Record record) {
		return getBaseMapper().selectCount(record);
	}

	@Override
	public Integer countByExample(Example example) {
		this.removeEmptyStringValue(example);
		return getBaseMapper().selectCountByExample(example);
	}

	@Override
	public Integer deleteByExample(Example example) {
		return getBaseMapper().deleteByExample(example);
	}

	@Override
	public Integer updateByExampleSelective(Record record, Example example) {
		record.setUpdateTime(new Date());
		return getBaseMapper().updateByExampleSelective(record, example);
	}
	
	private void removeEmptyStringValue(Example example) {
		List<Example.Criteria> list = example.getOredCriteria();
		for (int i = list.size() - 1; i >= 0; i--) {
			Example.Criteria criteria = list.get(i);
			List<Example.Criterion> criterionList = criteria.getCriteria();
			for (int j = criteria.getCriteria().size() - 1; j >= 0; j--) {
				Example.Criterion criterion = criterionList.get(j);
				Object value = criterion.getValue();
				if (value instanceof String) {
					if (StrUtil.isEmpty(String.valueOf(value))) {
						criteria.getCriteria().remove(criterion);
					}
				}
			}
		}
	}

}
